package com.bucket.cloud.auth.service.impl;

import com.bucket.cloud.auth.service.feign.GatewayInterfaceServiceClient;
import com.bucket.cloud.auth.service.feign.SystemUserServiceClient;
import com.bucket.cloud.common.core.constants.StateEnum;
import com.bucket.cloud.common.core.model.Result;
import com.bucket.cloud.common.core.security.AuthUserDetails;
import com.bucket.cloud.common.core.security.oauth2.client.OpenOAuth2ClientProperties;
import com.bucket.cloud.system.api.model.SystemInterface;
import com.bucket.cloud.system.api.vo.SystemUserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Security用户信息获取实现类
 *
 * @author cyq
 */
@Slf4j
@Service("userDetailService")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private SystemUserServiceClient client;
    @Autowired
    private OpenOAuth2ClientProperties clientProperties;

    @Resource
    private GatewayInterfaceServiceClient gatewayInterfaceServiceClient;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetails userDetails = null;
        try {
            SystemUserVO user = new SystemUserVO();
            user.setUsername(username);
            user.setState(StateEnum.ENABLE.getCode());
            user = client.login(user).getData();

            if (user != null) {
                Result retApis = gatewayInterfaceServiceClient.queryUserApis(user);
                List<SystemInterface> apis = (List<SystemInterface>) retApis.getData();
                if (apis != null) {
                    // 查询接口API权限
                    user.setApis(apis);
                }
                boolean accountNonLocked = true;
                boolean enabled = user.getState() == StateEnum.ENABLE.getCode() ? true : false;
                boolean accountNonExpired = true;
                boolean credentialsNonExpired = true;
                // 加载权限
                AuthUserDetails authUserDetails = new AuthUserDetails();
                authUserDetails.setId(user.getId());
                authUserDetails.setUsername(user.getUsername());
                authUserDetails.setPassword(user.getPassword());
                authUserDetails.setName(user.getName());
                authUserDetails.setEnabled(enabled);
                authUserDetails.setAccountNonExpired(accountNonExpired);
                authUserDetails.setCredentialsNonExpired(credentialsNonExpired);
                authUserDetails.setAccountNonLocked(accountNonLocked);
                authUserDetails.setUserType(user.getUserType());
                authUserDetails.setAuthorities(getAuthorities(user));
                authUserDetails.setAllResourcesTree(user.getAllResourcesTree());
                authUserDetails.setClientId(clientProperties.getOauth2().get("admin").getClientId());
                return authUserDetails;
            } else {
                if (user == null || user.getId() == null) {
                    throw new UsernameNotFoundException("系统用户 " + username + " 不存在!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return userDetails;
    }

    private Collection<GrantedAuthority> getAuthorities(SystemUserVO user) {
        List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
        List<SystemInterface> apis = user.getApis();
        for (SystemInterface api : apis) {
            if (StringUtils.isNotBlank(api.getId())) {
                authList.add(new SimpleGrantedAuthority(api.getId()));
            }
        }
        return authList;
    }

}
